#!/usr/bin/python
# -*- coding: utf-8 -*-

import datetime
import time
import traceback

from flask import Flask, g, request, jsonify

from v8.engine.handlers.user import get_user_info, get_user_contacts, \
    add_user, update_user_contacts
from v8.config import config

from config import V8_CONFIG, DEBUG
config.from_object(V8_CONFIG)  # noqa
from decorators import log_request, return_json
import rest_exceptions
import rest_log

app = Flask(__name__)
app.secret_key = 'green reading key'
app.config['SESSION_TYPE'] = 'filesystem'


@app.route('/get_contacts', methods=['GET'])
@return_json
@log_request
def get_contacts():
    user_name = request.args['user_name']
    contacts = get_user_contacts(user_name)
    if contacts is None:
        return {'contacts': []}
    else:
        for contact in contacts:
            if(contact['aliasname']):
                contact['display_name'] = contact['aliasname']
            elif(contact['nickname']):
                contact['display_name'] = contact['nickname']
            else:
                contact['display_name'] = contact['name']
        contacts.sort(key=lambda v: v['display_name'])
        return {'contacts': contacts}


@app.route('/register_user', methods=['POST'])
@return_json
@log_request
def register_user():
    user_info = {
        'name': request.form['name'],
        'password': request.form['password'],
        'phone': request.form['phone'],
        'nickname': request.form['nickname'],
        'logo': '',
    }
    _user = add_user(user_info)
    if _user is None:
        raise rest_exceptions.UserExistError(
            u'user name exist, try other name please')
    ret = {}
    for key in ['name', 'nickname', 'logo']:
        ret[key] = _user[key]
    ret['user_id'] = _user['id']
    return ret


@app.route('/login', methods=['POST'])
@return_json
@log_request
def login():
    name = request.form['name']
    password = request.form['password']
    _user = get_user_info(name)
    if _user is None or _user['password'] != password:
        raise rest_exceptions.WrongPassword(
            u'user not exist or password is wrong')
    ret = {}
    for key in ['name', 'nickname', 'logo']:
        ret[key] = _user[key]
    ret['user_id'] = _user['id']
    return ret


@app.before_request
def before_request():
    g.log_info = dict()
    if 'X-Real-IP' in request.headers:
        g.log_info['remote_addr'] = request.headers['X-Real-IP']
        g.remote_addr = request.headers['X-Real-IP']
    else:
        g.log_info['remote_addr'] = request.headers.get('X-Forwarded-For')
        g.remote_addr = request.headers.get('X-Forwarded-For')
    if not g.remote_addr:
        g.remote_addr = request.remote_addr
    g.log_info['request_data'] = request.data
    g.log_info['method'] = request.method
    g.log_info['url'] = request.url
    g.log_info['headers'] = dict(request.headers)
    g.log_info['form'] = dict(request.form)
    g.log_info['start_time'] = time.time()


@app.after_request
def after_request(response):
    g.log_info['end_time'] = time.time()
    g.log_info['process_time'] = \
        g.log_info['end_time'] - g.log_info['start_time']

    g.log_info['status_code'] = response.status_code
    g.log_info['ret_headers'] = dict(response.headers)

    if 400 <= response.status_code < 500:
        rest_log.logger.warning(g.log_info)
    else:
        rest_log.logger.info(g.log_info)

    response.headers['Date'] = \
        datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
    return response


@app.errorhandler(404)
def uri_not_found(exception):
    ret = dict()
    ret['code'] = 1000
    ret['error'] = 'uri_not_found'
    ret['request'] = ' '.join([request.method, request.url])
    return jsonify(ret), 404


@app.errorhandler(500)
def internal_server_error(exception):
    ret = dict()
    ret['code'] = 999
    ret['error'] = 'unknown_error'
    ret['request'] = ' '.join([request.method, request.url])
    ret['exception'] = str(exception)
    ret['detail'] = u'服务器维护中'
    return jsonify(ret), 500


@app.teardown_request
def teardown_request(exception):
    if getattr(g, 'log_info', None) is None:
        g.log_info = dict()

    if exception:
        g.log_info['exception'] = str(exception)
        g.log_info['format_exc'] = traceback.format_exc()
        rest_log.logger.critical(g.log_info)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5055, debug=DEBUG)
